#include "dbclient.h"

DBClient::DBClient()
{
	permision = PERM_NO;
	active = 1;
}

DBClient::~DBClient()
{
	//dtor
}



void DBClient::onReadyRead ( Pipe *p, i32 bytes, i32 userdata )
{
//	LOGP1 ( "READY" );
	DBClient *client = ( DBClient * ) userdata;

	if ( !userdata ) {
		EXCEX ( 0xFFFF, "ASSERT [userdata] failed" );
	}

	client->ReciveData ( bytes );
}

void DBClient::onDataSent ( Pipe *p, i32 bytes, i32 userdata )
{
}

void DBClient::onPipeError ( Pipe *p, i32 err_code, i32 userdata )
{
	DBClient *client = ( DBClient * ) userdata;
	LOGP2 ( "SERVER: TCP/IP Layer error. Connection to client closed. [#%X]", err_code );

	if ( WSAGetLastError() ) {
		LOGP2 ( "SERVER: Winsock error [%s]", ErrToStr ( WSAGetLastError() ).c_str() );
	}

	client->connection->Close ( 0 );
	client->active = 0;
}


void DBClient::AddBuffer ( void *data, i32 len )
{
	for ( i32 c = 0; c < len; c++ )
	{
		send_buff.push_back ( ( ( char * ) data ) + c );
	}
}

i32 DBClient::FlushBuffer()
{
	if ( !send_buff.size() )
	{
		LOGP1 ( "Flushing empty buffer ?" );
		return 0;
	}

	i32 res = connection->Send ( ( i8 * ) &send_buff[0], send_buff.size() );
	send_buff.empty();

	if ( !res )
	{
		LOGP3 ( "SERVER: ERROR FlushBuffer : WSA %d, Errno %d", WSAGetLastError(), errno );
		LOGP1 ( "SERVER: Sending buffer failed ! [Connection problem ?]" );
		active = 0;
		return 0;
	}

	return 1;
}


u16 DBClient::channelNum ( u32 device_id, u32 chann_num )
{
	u16 ret;

	if ( device_id > 127 ) // 7bit
	{
		device_id = 127;
		LOGP1 ( "SERVER: channelnum : dev_id exceed 7bit" );
	}

	if ( chann_num > 511 )
	{
		chann_num = 511;
		LOGP1 ( "SERVER: channelnum : chann_num exceed 9bit" );
	}

	ret = chann_num | ( device_id << 9 );
//	LOGP2 ( "chann %X", ret );
	return ret;
}

void DBClient::numChannel ( u16 coded, u32 &device_id, u32 &channel_num )
{
	device_id = ( coded & 0xFE00 ) >> 9;
	channel_num = ( coded & 0x01FF );
}

i32 DBClient::popBuffer ( void *data, i32 len )
{
	// do not call ENTER_CS here !!! It was called from function calling this  function
	if ( ( ( u32 ) len ) > connection->p_buff_recv.size() )
	{
		LOGP3 ( "LEN %d, buffer %d", len, connection->p_buff_recv.size() );
		active = 0;
		EXCEX ( 0xFFFF, "Buffer underflow" );
	}

	char *buff = ( char * ) data;

	for ( i32 c = 0; c < len; c++ )
	{
		buff[c] = connection->p_buff_recv[c];
	}

	connection->p_buff_recv.erase ( connection->p_buff_recv.begin(), connection->p_buff_recv.begin() + len );
	return len;
}

